package framework;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.function.Consumer;

public class InputSet{
	private Map<String, List<Object>> map = new HashMap<>();
	
	/**
	 * 为指定名称的输入项添加一项测试输入
	 * @param name 输入项名称
	 * @param value 测试输入
	 */
	public void add(String name, Object value){
		List<Object> list = map.get(name);
		if(list == null){
			list = new ArrayList<>();
			map.put(name, list);
		}
		
		list.add(value);
	}
	
	/**
	 * 删除指定名称的输入项的指定测试输入
	 * @param name 输入项名称
	 * @param value 测试输入
	 */
	public void remove(String name, Object value){
		List<Object> list = map.get(name);
		if(list != null)
			list.remove(value);
	}
	
	/**
	 * 组合所有输入项，并为每个组合执行给定的方法
	 * @param function 为每个组合所执行的方法
	 */
	public void every(Consumer<Map<String, Object>> function){
		Set<String> names = map.keySet();
		
		/**
		 * 用于存放所有输入项的组合索引。其元素格式为：“name:valueIndex_name:valueIndex”。
		 * 如："name:0_email:2"，代表输入项name的第一个取值与输入项email的第三个取值的组合。<br/>
		 */
		List<String> indexes = new ArrayList<>();
		/* 迭代集合，生成组合索引列表 */
		for(String name: names){
			List<String> newIndexes = new ArrayList<>();
			
			/* 取出当前名称输入项的取值个数 */
			int valueSize = map.get(name).size();
			
			if(indexes.isEmpty())/* 第一次迭代 */
				for(int i = 0; i < valueSize; i++){
					newIndexes.add(name + ":" + i);
				}
			else
				for(int i = 0; i < valueSize; i++){
					for(int j = 0; j < indexes.size(); j++)
						newIndexes.add(indexes.get(j) + "_" + name + ":" + i);
				}
			
			/* 更新索引集合 */
			indexes = newIndexes;
		}
		
		/* 根据索引信息遍历组合 */
		for(String index: indexes){
			Map<String, Object> input = new HashMap<>();
			
			String[] pairs = index.split("_");
			for(String pair: pairs){
				String[] segs = pair.split(":");
				
				/* 取出输入项名称和取值 */
				String name = segs[0];
				int valueIndex = Integer.parseInt(segs[1]);
				
				input.put(name, map.get(name).get(valueIndex));
			}
			
			function.accept(input);
		}
	};
}
